/* Estimation.ado (STATA)
	Estimate demand.
	by Ralph Koijen & Motohiro Yogo */

#delimit ;

program Estimation;
args n ymax;


/* Step 1: Construct IV for asset quantities */

/* Load data */

u Prediction`n', clear;

xtset year;

/* Aggregate across the euro area */

foreach var of varlist quant gdpP pop {;
	egen T`var' = total(`var'*Iycounterpart), missing by(year counter_euro type);

	gen LT`var' = ln(T`var');

	drop T`var';
};

/* Predict quantities by asset class */

gen IVLquant = .;

qui forval j = 1/3 {;
	xtreg LTquant LTgdpP LTpop
		if year<=`ymax' & type==`j' & Iycounter_euro, fe vce(robust);

	predict LTquant_pred if year<=`ymax' & type==`j', xb;	/* Without fixed effects */

	replace IVLquant = LTquant_pred if year<=`ymax' & type==`j';

	drop LTquant_pred;
};

drop LTquant LTgdpP LTpop;


/* Step 2: Construct IV for inner nest */

/* Predict demand within asset class */

gen delta = .;

qui forval j = 1/3 {;
	xtreg Lrw dist
		if year<=`ymax' & !inlist(country,"_CR","_OC") & type==`j', fe vce(robust);

	predict Ldelta if year<=`ymax' & !inlist(country,"_CR","_OC") & type==`j', xb;	/* Without fixed effects */

	replace delta = exp(Ldelta) if year<=`ymax' & !inlist(country,"_CR","_OC") & type==`j';

	drop Ldelta;
};

/* Construct inner portfolio weights */

egen Sdelta = total(delta), missing by(year country type);
replace Sdelta = 1+Sdelta;

gen weight = delta/Sdelta;

drop delta Sdelta;

/* Predict demand across asset classes */

reg LrwealthA $dummiesA
	if year<=`ymax' & Iycountry, nocons robust;

predict LlatentA, xb;

/* Construct outer portfolio weights */

gen latentA = exp(LlatentA);

egen TlatentA = total(latentA*Iycountry), missing by(year country);

gen weightA = latentA/TlatentA;

drop LlatentA latentA TlatentA;

/* Construct wealth */

egen Tweight = total(weight*weightA), missing by(year country);

gen wealthIV = outside/(1-Tweight);

drop Tweight;

/* Construct IV */

gen IVLdemand = .;
gen IVexdemand = .;

levelsof country;

qui foreach i in `r(levels)' {;

	/* Counterfactual demand excluding own holdings */

	egen demand = total(wealthIV*weight*weightA*(country!="`i'")), missing by(year counter_euro type);

	replace IVLdemand = ln(demand) if country=="`i'";

	drop demand;

	/* Counterfactual excess demand */

	replace IVexdemand = IVLdemand-IVLquant if country=="`i'";
};

drop weight weightA wealthIV;


/* Step 3: Estimate demand within asset class */

/* Construct variables */

gen eps = .;

qui foreach var of varlist Eret $macro $bilateral $dummies {;
	gen b_`var' = .;

	label var b_`var' "Coefficient: `var'";
};

gen b_cons = .;

/* Estimation by asset type */

qui forval j = 1/3 {;

	/* First stage */
	
	reg Eret $iv $macro $bilateral $dummies
		if year<=`ymax' & type==`j', robust;

	eststo Eret`j';

	/* Test for weak IV */

	ivregress 2sls Lrw (Eret = $iv) $macro $bilateral $dummies
		if year<=`ymax' & type==`j';

	nois estat first;

	/* Estimate demand */

	ivregress 2sls Lrw (Eret = $iv) $macro $bilateral $dummies
		if year<=`ymax' & type==`j', robust;

	eststo Lrw`j';

	/* Estimate latent demand */

	predict resid if type==`j', resid;

	replace eps = resid if type==`j';

	drop resid;

	/* Save coefficients */

	foreach var of varlist Eret $macro $bilateral $dummies {;
		replace b_`var' = _b[`var'] if type==`j';
	};

	replace b_cons = _b[_cons] if type==`j';

	mata: b`j' = st_matrix("e(b)");
	mata: Var_b`j' = st_matrix("e(V)");
};

/* Save coefficients and covariance matrix */

mata: mata matsave Estimation`n' b* Var_b*, replace;

/* Output table */

esttab Eret*, b(%8.2f) se(%8.2f) plain
	drop(Iyear_*);

esttab Lrw*, b(%8.2f) se(%8.2f) plain
	drop(Iyear_*);

eststo clear;


/* Step 4: Construct IV for outer nest */

/* Estimate demand shifter */

gen shifter = Lrw-b_Eret*Eret;

/* Predict demand within asset class */

gen delta = .;

levelsof country if year<=`ymax';

qui foreach i in `r(levels)' {;
	forval j = 1/3 {;
		reg shifter Iown
			if year<=`ymax' & country=="`i'" & type==`j', robust;

		predict Ldelta if year<=`ymax' & country=="`i'" & type==`j', xb;

		replace delta = exp(Ldelta) if year<=`ymax' & country=="`i'" & type==`j';

		drop Ldelta;
	};
};

drop shifter;

/* Construct IV */

egen Sdelta = total(delta), missing by(year country type);
replace Sdelta = 1+Sdelta;

forval j = 1/2 {;
	gen LSdelta`j' = ln(Sdelta)*(type==`j') if type!=3;
};

sort year country type counterpart;
by year country: gen LSdelta3 = -ln(Sdelta[_N]) if type!=3 & type[_N]==3;

drop delta Sdelta;


/* Step 5: Estimate demand across asset classes */

/* First stage */

qui forval j = 1/3 {;
	reg LSrw`j' $ivA $dummiesA
		if year<=`ymax' & Iycountry, nocons robust;
	eststo LSrw`j';
};

/* Test for weak IV */

qui ivregress 2sls LrwealthA (LSrw* = $ivA) $dummiesA
	if year<=`ymax' & Iycountry, nocons;

estat first;

/* Estimate demand */

qui ivregress 2sls LrwealthA (LSrw* = $ivA) $dummiesA
	if year<=`ymax' & Iycountry, nocons robust;

eststo LrwealthA;

/* Estimate latent demand */

predict epsA, resid;
replace epsA = 0 if type==3;

/* Save coefficients */

foreach var of varlist LSrw* {;
	gen bA_`var' = _b[`var'];

	label var bA_`var' "Aggregate coefficient: `var'";
};

gen bA_cons = 0;

foreach var of varlist $dummiesA {;
	replace bA_cons = bA_cons+_b[`var']*`var' if type!=3;
};

/* Output table */

esttab LSrw*, b(%8.2f) se(%8.2f) plain;

esttab LrwealthA, b(%8.2f) se(%8.2f) plain;

eststo clear;

/* Label variables */

label var IVLquant		"IV: Predicted log quantity";
label var IVLdemand		"IV: Predicted log demand";
label var IVexdemand	"IV: Excess log demand";

label var LSdelta1		"IV: LSrw1";
label var LSdelta2		"IV: LSrw2";
label var LSdelta3		"IV: LWrw3";

label var eps			"Latent demand";
label var b_cons		"Coefficient: Constant";
label var epsA			"Aggregate latent demand";
label var bA_cons		"Aggregate coefficient: Constant";

/* Save data */

sort year country counterpart type;

save Estimation`n', replace;

end;
